package at.fhooe.tof.app;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Label;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.EventObject;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSlider;
import javax.swing.border.EmptyBorder;

import at.fhooe.tof.bl.StateManager;
import at.fhooe.tof.fileread.TOFHandler;
import at.fhooe.tof.fileread.TOFStreaming;
import at.fhooe.tof.mockup.ITOFMockupListener;
import at.fhooe.tof.mockup.TOFMockupEventSource;
import at.fhooe.tof.mockup.TOFStreamMockup;

public class MainProgram extends JFrame implements IObserverSubscriber, ITOFMockupListener{
	private JPanel contentPane;
	private JFrame jFrame;	
	private JPanel jPanel;
	private JPanel jBackgroundPanel;
	private BufferedImage bufferedImage;
	private JLabel picLabel;
	static TOFStreamMockup mockup = null;
	static TOFHandler tofHandler = null;
	private static TOFMockupEventSource src = null;
	static int fromIndex = 128;
	private static TOFStreaming tofLive = null;
	private JLabel lblFreq = null;
	private JLabel lblAmpl = null;
	private JProgressBar amplScale = null;
	private JProgressBar freqScale = null;
	private JSlider distanceSlider = null;
	
	public static TOFMockupEventSource getSrcListener(){
		return src;
	}
	
	public MainProgram(){
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setTitle("Theremin App with TOFCam - PLAY SOME MUSIC!");
		setBounds(100, 100, 600, 400);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		GridBagLayout gbl_contentPane = new GridBagLayout();
		gbl_contentPane.columnWidths = new int[]{0, 0};
		gbl_contentPane.rowHeights = new int[]{0, 0, 0};
		gbl_contentPane.columnWeights = new double[]{1.0, Double.MIN_VALUE};
		gbl_contentPane.rowWeights = new double[]{1.0, 1.0, Double.MIN_VALUE};
		contentPane.setLayout(gbl_contentPane);
		
		FlowLayout mainLayout = new FlowLayout();
		
		JPanel videoPanel = new JPanel(mainLayout);
		GridBagConstraints gbc_videoPanel = new GridBagConstraints();
		gbc_videoPanel.insets = new Insets(0, 0, 5, 0);
		gbc_videoPanel.fill = GridBagConstraints.BOTH;
		gbc_videoPanel.gridx = 0;
		gbc_videoPanel.gridy = 0;
		contentPane.add(videoPanel, gbc_videoPanel);
	    
		jBackgroundPanel = new JPanel(mainLayout);
		jBackgroundPanel.setBackground(Color.ORANGE);
	    try{
	    	distanceSlider = new JSlider(JSlider.HORIZONTAL, 0, 20, 10);
	    	distanceSlider.setMajorTickSpacing(10);
	    	distanceSlider.setMinorTickSpacing(1);
	    	distanceSlider.setPaintTicks(true);
	    	distanceSlider.setPaintLabels(true);
	    	lblFreq = new JLabel("[frequency]");
	    	amplScale = new JProgressBar(JProgressBar.VERTICAL, 0, 100);
	    	amplScale.setStringPainted(true);
	    	freqScale = new JProgressBar(JProgressBar.VERTICAL, 0, 100);
	    	freqScale.setStringPainted(true);
	    	lblAmpl = new JLabel("[amplitude]");
	    	File file = new File(".\\output\\out.jpg");
	    	picLabel = new JLabel();
	    	jBackgroundPanel.add(picLabel);
	    	if(file.exists()){
	    		bufferedImage = ImageIO.read(file);
	    		picLabel.setIcon(new ImageIcon( bufferedImage ));
	    	}
	    	videoPanel.add(lblFreq);
	    	videoPanel.add(freqScale);
	    	videoPanel.add( jBackgroundPanel );
	    	videoPanel.add(amplScale);
	    	videoPanel.add(lblAmpl);
			
			JPanel distancePanel = new JPanel(mainLayout);
			GridBagConstraints gbc_distancePanel = new GridBagConstraints();
			gbc_distancePanel.fill = GridBagConstraints.BOTH;
			gbc_distancePanel.gridx = 0;
			gbc_distancePanel.gridy = 1;
			contentPane.add(distancePanel, gbc_distancePanel);
	    	distancePanel.add(new Label("Distance from Camera"));
	    	distancePanel.add(distanceSlider);
		   
	    }catch(Exception e){
	    	e.printStackTrace();
	    }
	    validate();
	    setVisible(true);
		
		
		
	}

	public static void main(String[] args){
        MainProgram prog = new MainProgram();
        Observer.register(prog);
        try {
        	File libPMDaccess = new File("libs/clibs/bin/pmdaccess2.dll");
    		File libTOFStreaming = new File("libs/clibs/TOFStreaming.dll");
    		System.load(libPMDaccess.getAbsolutePath());
    		System.load(libTOFStreaming.getAbsolutePath());
    		
    		//********* live stream ***********
    		tofHandler = new TOFHandler();
    		tofLive = new TOFStreaming();
    		tofLive.initStream();
    		float[] fArray;    		
    		while(true){
    			fArray = tofLive.getStream();
    			//TODO: better performance fArray = tofLive.getStream(fArray);
    			tofHandler.readTOFStream(fArray);
    		}
    		
    		
    		//********* mockup ***********//
//    		tofHandler = new TOFHandler();
//    		mockup = new TOFStreamMockup();
//    		mockup.init();
//    		mockup.streamMockupFloat(fromIndex);
    		
        	
    		//******** from file *********//
			//File file = new File(".\\tofs\\dump-2013-04-16-140357.tof");
        	//Path path = file.toPath();
			//tofHandler.readTOFFile(path);
			
			
		} catch (Exception e) {
			tofLive.close();
			e.printStackTrace();
		}
	}

	@Override
	public void receive(String msg) {
		try{
			if(msg.contains("amplitude")){
				String[] amp = msg.split("amplitude");
				Double ampValue;
				ampValue = Double.parseDouble(amp[1]);
				amplScale.setValue(ampValue.intValue());
			}else if(msg.contains("frequency")){
				String[] freq = msg.split("frequency");
				Double freqValue;
				freqValue = Double.parseDouble(freq[1]);
				freqScale.setValue(freqValue.intValue()-20);
			}else if(msg.contains(StateManager.idleColor)){
				jBackgroundPanel.setBackground(Color.ORANGE);
				jBackgroundPanel.revalidate();
				jBackgroundPanel.repaint();
			}else if(msg.contains(StateManager.standbyColor)){
				jBackgroundPanel.setBackground(Color.YELLOW);
				jBackgroundPanel.revalidate();
				jBackgroundPanel.repaint();
			}else if(msg.contains(StateManager.goColor)){
				jBackgroundPanel.setBackground(Color.GREEN);
				jBackgroundPanel.revalidate();
				jBackgroundPanel.repaint();
				//jFrame.revalidate();
				//jFrame.repaint();
			}else if(msg.contains("dist")){
				double distance = Double.parseDouble(msg.split("dist")[1]);
				distanceSlider.setValue((int)(distance*10));
			}

	    }catch(Exception e){
	    	e.printStackTrace();
	    }
	}

	@Override
	public void handleTOFMockupEvent(EventObject e) {
		float[] img = mockup.getImageFloat();
		tofHandler.readTOFStream(img);
		fromIndex+=120*160*4+128;
		mockup.streamMockupFloat(fromIndex);
	}

	@Override
	public void receive(Image image) {
		if(image != null){
			ImageIcon icon = new ImageIcon( image );
	    	picLabel.setIcon(icon);
			jBackgroundPanel.revalidate();
			jBackgroundPanel.repaint();
		}
	}
	
}
